﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Data;
using System.Web.UI;
using System.Web.UI.WebControls;
using AAA.Base.Util;
using System.Web;

namespace AAA.WebController
{
    public class ControlHelper
    {
        public const string SINGLE_VALUE_TABLE = "SingleValueTable";
        
        public const string SINGLE_VALUE_TABLE_CLIENT_ID = "SingleValueTableClientId";


        private static IEnumerable<Control> EnumerateControlsRecursive(Control parent)
        {
            foreach (Control child in parent.Controls)
            {
                yield return child;

                if(!(child is GridView))
                    foreach (Control descendant in EnumerateControlsRecursive(child))
                        yield return descendant;
            }
        }       

        private static object[] ParseControl(Control ctrlCell)
        {
            object[] oReturns = null;
            string strSelectedText = "";
            string strSelectedValue = "";
            
            try
            {
                if (ctrlCell is CheckBox)
                {                    
                    oReturns = new object[] { ((CheckBox)ctrlCell).Checked ?  true : false};
                    return oReturns;
                }

                if (ctrlCell is TextBox)
                {
                    oReturns = new object[] {((TextBox)ctrlCell).Text};
                    return oReturns;
                }

                if (ctrlCell is LinkButton)
                {
                    oReturns = new object[] { ((LinkButton)ctrlCell).Text };
                    return oReturns;
                }

                if (ctrlCell is Label)
                {
                    oReturns = new object[] { ((Label)ctrlCell).Text };
                    return oReturns;
                }

                if (ctrlCell is Image)
                {
                    oReturns = new object[] { ((Image)ctrlCell).ImageUrl };
                    return oReturns;
                }

                if (ctrlCell is HiddenField)
                {
                    oReturns = new object[] { ((HiddenField)ctrlCell).Value };
                    return oReturns;
                }

                if (ctrlCell is DropDownList)
                {
                    if (((DropDownList)ctrlCell).SelectedItem == null)
                        return oReturns;

                    oReturns = new object[] { ((DropDownList)ctrlCell).SelectedItem.Text, ((DropDownList)ctrlCell).SelectedItem.Value };
                    return oReturns;
                }

                if (ctrlCell is CheckBoxList)
                {
                    if (((CheckBoxList)ctrlCell).SelectedItem == null)
                        return oReturns;

                    foreach (ListItem listItem in ((CheckBoxList)ctrlCell).Items)
                    {
                        if (listItem.Selected)
                        {
                            strSelectedText += "," + listItem.Text;
                            strSelectedValue += "," + listItem.Value;
                        }
                    }

                    oReturns = new object[] { strSelectedText.Length > 0 ? strSelectedText.Substring(1) : null, 
                                              strSelectedValue.Length > 0 ? strSelectedValue.Substring(1) : null };
                    return oReturns;
                }

                if (ctrlCell is RadioButtonList)
                {
                    if (((RadioButtonList)ctrlCell).SelectedItem == null)
                        return oReturns;

                    oReturns = new object[] { ((RadioButtonList)ctrlCell).SelectedItem.Text, ((RadioButtonList)ctrlCell).SelectedItem.Value };
                    return oReturns;
                }

                if (ctrlCell is ListBox)
                {
                    if (((ListBox)ctrlCell).SelectedItem == null)
                        return oReturns;

                    oReturns = new object[] { ((ListBox)ctrlCell).SelectedItem.Text, ((ListBox)ctrlCell).SelectedItem.Value };
                    return oReturns;
                }
            }
            catch (Exception ex)
            {
                throw;
            }

            return oReturns;
        }

        public static string GetValue(DataTable dtSource, string strField)
        {
            return GetValue(dtSource, strField, null);
        }

        public static string GetValue(DataTable dtSource, string strField, int iRowIndex)
        {
            return GetValue(dtSource, strField, null, iRowIndex);
        }

        public static string GetValue(DataTable dtSource, string strField, string strNullValue)
        {
            return GetValue(dtSource, strField, strNullValue, 0);
        }

        public static string GetValue(DataTable dtSource, string strField, string strNullValue, int iRowIndex)
        {
            if (dtSource == null)
                return strNullValue;

            if ((dtSource.Rows.Count == 0) || (dtSource.Columns.Contains(strField) == false))
                return strNullValue;

            return dtSource.Rows[iRowIndex][strField].ToString();
        }

        private static void CreateColumns(DataTable dtSource, GridView gvSource, string[] strIDs)
        {
            // add the columns to the datatable            
            if (gvSource.HeaderRow != null)
            {
                if (strIDs != null)
                {
                    for (int i = 0; i < strIDs.Length; i++)
                    {
                        dtSource.Columns.Add(strIDs[i]);
                    }
                }
                else
                {
                    for (int i = 0; i < gvSource.HeaderRow.Cells.Count; i++)
                    {
                        dtSource.Columns.Add(gvSource.HeaderRow.Cells[i].Text);
                    }
                }
            }
        }

        private static void CreateColumns(DataTable dtSource, DataList dlSource, string[] strIDs)
        {
            if (strIDs != null)
            {
                for (int i = 0; i < strIDs.Length; i++)
                {
                    dtSource.Columns.Add(strIDs[i], typeof(string));
                    dtSource.Columns[strIDs[i]].ReadOnly = false;
                }
                return;
            }

            if (dlSource.Items.Count == 0)
                return;

            foreach (Control ctrlChild in EnumerateControlsRecursive(dlSource.Items[0]))
            {
                if (string.IsNullOrEmpty(ctrlChild.ID))
                    continue;

                dtSource.Columns.Add(ctrlChild.ID, typeof(string));
                dtSource.Columns[ctrlChild.ID].ReadOnly = false;
            }
            
        }

        private static void FillRow(DataRow dr, GridViewRow row, string[] strIDs)
        {
            Control ctrlCell;
            object[] oReturns;

            for (int i = 0; i < Math.Min(dr.Table.Columns.Count, row.Cells.Count); i++)
            {
                if ((strIDs != null) && (i < strIDs.Length))
                {
                    if ((ctrlCell = row.Cells[i].FindControl(strIDs[i])) != null)
                    {
                        oReturns = ParseControl(ctrlCell);
                        dr[i] = oReturns != null ? oReturns[0].ToString() : null;
                    }
                    else
                        dr[i] = row.Cells[i].Text.Replace(" ", "");
                }
                else
                {
                    dr[i] = row.Cells[i].Text.Replace(" ", "");
                }

            }
        }

        private static void FillRow(DataRow dr, DataListItem listItem, string[] strIDs)
        {
            Control ctrlCell;
            object[] oReturns;
            string strControlId;

            for (int i = 0; i < dr.Table.Columns.Count; i++)
            {
                if ((strIDs != null) && (i < strIDs.Length))
                    strControlId = strIDs[i];
                else
                    strControlId = dr.Table.Columns[i].ColumnName;

                if ((ctrlCell = listItem.FindControl(strControlId)) != null)
                {
                    oReturns = ParseControl(ctrlCell);
                    dr[i] = oReturns != null ? oReturns[0].ToString() : null;
                }
                else
                {
                    dr[i] = null;
                }
            }
        }

        public static DataTable GetDataTable(GridView gvSource)
        {
            return GetDataTable(gvSource, null);
        }
               
        public static DataTable GetDataTable(GridView gvSource, string[] strIDs)
        {
            DataTable dt = new DataTable();
            DataRow dr;

            CreateColumns(dt, gvSource, strIDs);

            //  add each of the data rows to the table
            foreach (GridViewRow row in gvSource.Rows)
            {
                dr = dt.NewRow();
                
                FillRow(dr, row, strIDs);
  
                dt.Rows.Add(dr);
            }
            return dt;
        }

        public static DataTable GetDataList(DataList dlSource)
        {
            return GetDataList(dlSource, null);
        }

        public static DataTable GetDataList(DataList dlSource, string[] strIDs)
        {
            DataTable dt = new DataTable();
            DataRow dr;

            CreateColumns(dt, dlSource, strIDs);

            //  add each of the data rows to the table
            foreach(DataListItem listItem in dlSource.Items)
            {
                dr = dt.NewRow();

                FillRow(dr, listItem, strIDs);

                dt.Rows.Add(dr);
            }
            return dt;
        }


        public static DataTable GetSelectedRow(GridView gvSource)
        {
            return GetSelectedRow(gvSource, null);
        }

        public static DataTable GetSelectedRow(GridView gvSource, string[] strIDs)
        {
            DataTable dt = new DataTable();
            DataRow dr;

            CreateColumns(dt, gvSource, strIDs);

            //  add each of the data rows to the table
            GridViewRow row = gvSource.SelectedRow;
            
            if(row == null)
                return null;

            dr = dt.NewRow();
            
            FillRow(dr, row, strIDs);

            dt.Rows.Add(dr);

            return dt;
        }

        public static void ClearAllControl(Control ctrlParent)
        {
            ClearAllControl(ctrlParent, null, true);
        }



        public static void ClearAllControl(Control ctrlParent, bool isRecursive)
        {
            ClearAllControl(ctrlParent, null, isRecursive);
        }

        public static void ClearAllControl(Control ctrlParent, ListItem clearItem)
        {
            ClearAllControl(ctrlParent, clearItem, true);
        }

        public static void ClearAllControl(Control ctrlParent, ListItem clearItem, bool isRecursive)
        {
            if (isRecursive)
            {
                foreach (Control ctrlChild in EnumerateControlsRecursive(ctrlParent))
                    ClearControl(ctrlChild, clearItem);
            }
            else
            {
                foreach (Control ctrlChild in ctrlParent.Controls)
                    ClearControl(ctrlChild, clearItem);
            }
        }

        public static void ClearControl(Control ctrlTarget)
        {
            ClearControl(ctrlTarget, null);
        }

        public static void ClearControl(Control ctrlTarget, ListItem clearItem)
        {
            if (ctrlTarget is CheckBox)
            {
                ((CheckBox)ctrlTarget).Checked = false;
            }

            if(ctrlTarget is TextBox)
            {
                ((TextBox)ctrlTarget).Text = "";
            }

            if (ctrlTarget is Label)
            {
                ((Label)ctrlTarget).Text = "";
            }

            if (ctrlTarget is LinkButton)
            {
                ((LinkButton)ctrlTarget).Text = "";
            }


            if (ctrlTarget is HiddenField)
            {
                ((HiddenField)ctrlTarget).Value = "";
            }

            if (ctrlTarget is Image)
            {
                ((Image)ctrlTarget).ImageUrl = "";
            }

            if (ctrlTarget is DropDownList)
            {
                ((DropDownList)ctrlTarget).Items.Clear();

                if (clearItem != null)
                    ((DropDownList)ctrlTarget).Items.Add(clearItem);

                if(((DropDownList)ctrlTarget).Items.Count > 0)
                    ((DropDownList)ctrlTarget).SelectedIndex = 0;
            }

            if (ctrlTarget is RadioButtonList)
            {
                ((RadioButtonList)ctrlTarget).Items.Clear();

                if (clearItem != null)
                    ((RadioButtonList)ctrlTarget).Items.Add(clearItem);

                if (((RadioButtonList)ctrlTarget).Items.Count > 0)
                    ((RadioButtonList)ctrlTarget).Items[0].Selected = true;
            }

            if (ctrlTarget is CheckBoxList)
            {
                ((CheckBoxList)ctrlTarget).Items.Clear();

                if (clearItem != null)
                    ((CheckBoxList)ctrlTarget).Items.Add(clearItem);

                if (((CheckBoxList)ctrlTarget).Items.Count > 0)
                    ((CheckBoxList)ctrlTarget).Items[0].Selected = true;
            }

            if (ctrlTarget is ListBox)
            {
                ((ListBox)ctrlTarget).Items.Clear();

                if (clearItem != null)
                    ((ListBox)ctrlTarget).Items.Add(clearItem);

                if (((ListBox)ctrlTarget).Items.Count > 0)
                    ((ListBox)ctrlTarget).SelectedIndex = 0;
            }
            
        }


        private static void SetValue(Control ctrlTarget, string strColumnName, DataTable dtData)
        {
            SetValue(ctrlTarget, strColumnName, dtData, 0);
        }

        private static void SetValue(Control ctrlTarget, string strColumnName, DataTable dtData, int iRowIndex)
        {
            SetValue(ctrlTarget, strColumnName, dtData, iRowIndex, true);
        }

        private static void SetValue(Control ctrlTarget, string strColumnName, DataTable dtData, int iRowIndex, bool isClearNotMatchControl)
        {
            List<string> lstSelectedText;

            if((dtData.Columns.Contains(strColumnName) == false) ||
               (dtData.Rows.Count <= iRowIndex))
            {
                if ((!(ctrlTarget is DropDownList)) &&
                   (!(ctrlTarget is ListBox)))
                {
                    if(isClearNotMatchControl)
                        ClearControl(ctrlTarget);
                }
                return;
            }

            if (ctrlTarget is TextBox)
            {
                ((TextBox)ctrlTarget).Text = HttpUtility.HtmlDecode(StringHelper.ToString(dtData.Rows[iRowIndex][strColumnName]));
                return;
            }

            if (ctrlTarget is Image)
            {
                ((Image)ctrlTarget).ImageUrl = HttpUtility.HtmlDecode(StringHelper.ToString(dtData.Rows[iRowIndex][strColumnName]));
                return;
            }

            if (ctrlTarget is ImageButton)
            {
                ((ImageButton)ctrlTarget).ImageUrl = HttpUtility.HtmlDecode(StringHelper.ToString(dtData.Rows[iRowIndex][strColumnName]));
                return;
            }

            if (ctrlTarget is CheckBox)
            {
                ((CheckBox)ctrlTarget).Checked = StringHelper.ToString(dtData.Rows[iRowIndex][strColumnName]) == "Y";
                return;
            }

            if (ctrlTarget is Literal)
            {
                ((Literal)ctrlTarget).Text = HttpUtility.HtmlDecode(StringHelper.ToString(dtData.Rows[iRowIndex][strColumnName]));
                return;
            }

            if (ctrlTarget is Label)
            {
                ((Label)ctrlTarget).Text = HttpUtility.HtmlDecode(StringHelper.ToString(dtData.Rows[iRowIndex][strColumnName]));
                return;
            }

            if (ctrlTarget is LinkButton)
            {
                ((LinkButton)ctrlTarget).Text = StringHelper.ToString(dtData.Rows[iRowIndex][strColumnName]);
                return;
            }

            if (ctrlTarget is HiddenField)
            {
                ((HiddenField)ctrlTarget).Value = StringHelper.ToString(dtData.Rows[iRowIndex][strColumnName]);
                return;
            }

            if (ctrlTarget is RadioButtonList)
            {
                for (int i = 0; i < ((RadioButtonList)ctrlTarget).Items.Count; i++)
                    ((RadioButtonList)ctrlTarget).Items[i].Selected = false;

                for (int i = 0; i < ((RadioButtonList)ctrlTarget).Items.Count; i++)
                {
                    if (((RadioButtonList)ctrlTarget).Items[i].Text == StringHelper.ToString(dtData.Rows[iRowIndex][strColumnName]))
                    {
                        ((RadioButtonList)ctrlTarget).Items[i].Selected = true;
                        break;
                    }
                }
                return;
            }

            if (ctrlTarget is CheckBoxList)
            {
                for (int i = 0; i < ((CheckBoxList)ctrlTarget).Items.Count; i++)
                    ((CheckBoxList)ctrlTarget).Items[i].Selected = false;

                lstSelectedText = new List<string>(StringHelper.ToString(dtData.Rows[iRowIndex][strColumnName]).Split(','));

                for (int i = 0; i < ((CheckBoxList)ctrlTarget).Items.Count; i++)
                {
                    if (lstSelectedText.Contains(((CheckBoxList)ctrlTarget).Items[i].Text))
                    {
                        ((CheckBoxList)ctrlTarget).Items[i].Selected = true;
                        break;
                    }
                }
                return;
            }


            if (ctrlTarget is DropDownList)
            {
                for (int i = 0; i < ((DropDownList)ctrlTarget).Items.Count; i++)
                {
                    if (((DropDownList)ctrlTarget).Items[i].Text == StringHelper.ToString(dtData.Rows[iRowIndex][strColumnName]))
                    {
                        ((DropDownList)ctrlTarget).SelectedIndex = i;
                        break;
                    }
                }
                return;
            }

            if (ctrlTarget is ListBox)
            {
                for (int i = 0; i < ((ListBox)ctrlTarget).Items.Count; i++)
                {
                    if (((ListBox)ctrlTarget).Items[i].Text == StringHelper.ToString(dtData.Rows[iRowIndex][strColumnName]))
                    {
                        ((ListBox)ctrlTarget).SelectedIndex = i;
                        break;
                    }
                }
                return;
            }
        }

        public static void InitControl(Control container, string strControlId, string strDataTableName, DataSet dsData)
        {
            InitControl(container, strControlId, strDataTableName, null, dsData);
        }

        public static void InitControl(Control ctrlTarget, DataTable dtData)
        {
            InitControl(ctrlTarget, null, dtData);
        }

        public static void InitControl(Control ctrlTarget, string strColumnName, DataTable dtData)
        {

            if ((ctrlTarget is TextBox) ||
                (ctrlTarget is CheckBox) ||
                (ctrlTarget is Label) ||
                (ctrlTarget is Image) ||
                (ctrlTarget is ImageButton) ||
                (ctrlTarget is LinkButton) ||
                (ctrlTarget is HiddenField))
            {
                SetValue(ctrlTarget, strColumnName, dtData);
                return;
            }

            if ((ctrlTarget is RadioButtonList))
            {
                ((RadioButtonList)ctrlTarget).DataSource = dtData;
                ((RadioButtonList)ctrlTarget).DataBind();
            }

            if ((ctrlTarget is CheckBoxList))
            {
                ((CheckBoxList)ctrlTarget).DataSource = dtData;
                ((CheckBoxList)ctrlTarget).DataBind();
            }

            if ((ctrlTarget is DropDownList))
            {
                ((DropDownList)ctrlTarget).DataSource = dtData;
                ((DropDownList)ctrlTarget).DataBind();
            }

            if ((ctrlTarget is ListBox))
            {
                ((ListBox)ctrlTarget).DataSource = dtData;
                ((ListBox)ctrlTarget).DataBind();
            }
        }

        public static void InitControl(Control container, string strControlId, string strDataTableName, string strColumnName, DataSet dsData)
        {
            try
            {
                if ((container.FindControl(strControlId) == null) ||
                    (dsData.Tables.Contains(strDataTableName) == false))
                    return;

                Control ctrlTarget = container.FindControl(strControlId);

                if ((ctrlTarget is TextBox) ||
                    (ctrlTarget is CheckBox) ||
                    (ctrlTarget is Label) ||
                    (ctrlTarget is Image) ||
                    (ctrlTarget is ImageButton) ||
                    (ctrlTarget is LinkButton) ||
                    (ctrlTarget is HiddenField))
                {
                    InitControl(ctrlTarget, strColumnName, dsData.Tables[strDataTableName]);
                    
                    return;
                }

                if ((ctrlTarget is RadioButtonList) ||
                    (ctrlTarget is CheckBoxList) || 
                    (ctrlTarget is DropDownList) ||
                    (ctrlTarget is ListBox))
                {
                    InitControl(ctrlTarget, dsData.Tables[strDataTableName]);
                    return;
                }

                if ((ctrlTarget is GridView))
                {
                    ((GridView)ctrlTarget).DataSource = dsData.Tables[strDataTableName];
                    ((GridView)ctrlTarget).DataBind();
                    return;
                }

                if ((ctrlTarget is DataList))
                {
                    ((DataList)ctrlTarget).DataSource = dsData.Tables[strDataTableName];
                    ((DataList)ctrlTarget).DataBind();
                    return;
                }
            }
            catch (Exception ex)
            {

            }
        }

        public static void SetControlValue(Control container, DataSet dataSet)
        {
            SetControlValue(container, dataSet, true, true);
        }

        public static void SetControlValue(Control container, DataSet dataSet, Dictionary<string, string> dicIdMapping)
        {
            SetControlValue(container, dataSet, dicIdMapping, true);
        }

        public static void SetControlValue(Control container, DataSet dataSet, Dictionary<string, string> dicIdMapping, bool isClearNotMatchControl)
        {
            SetControlValue(container, dataSet, ControlHelper.SINGLE_VALUE_TABLE, dicIdMapping, isClearNotMatchControl);
        }


        public static void SetControlValue(Control container, DataSet dataSet, string strTableName)
        {
            SetControlValue(container, dataSet, strTableName, new Dictionary<string, string>());
        }

        public static void SetControlValue(Control container, DataSet dataSet, string strTableName, Dictionary<string, string> dicIdMapping)
        {
            SetControlValue(container, dataSet, strTableName, dicIdMapping, true);
        }

        public static void SetControlValue(Control container, DataSet dataSet, string strTableName, Dictionary<string, string> dicIdMapping, bool isClearNotMatchControl)
        {
            SetControlValue(container, dataSet, true, strTableName, dicIdMapping, isClearNotMatchControl);
        }

        public static void SetControlValue(Control container, DataSet dataSet, bool needTrimPrefix)
        {
            SetControlValue(container, dataSet, needTrimPrefix, true);
        }

        public static void SetControlValue(Control container, DataSet dataSet, bool needTrimPrefix, bool isClearNotMatchControl)
        {
            SetControlValue(container, dataSet, needTrimPrefix, ControlHelper.SINGLE_VALUE_TABLE, new Dictionary<string, string>());
        }

        public static void SetControlValue(Control container, DataSet dataSet, bool needTrimPrefix, string strTableName, Dictionary<string, string> dicIdMapping)
        {
            SetControlValue(container, dataSet, needTrimPrefix, strTableName, dicIdMapping, true);
        }

        public static void SetControlValue(Control container, DataSet dataSet, bool needTrimPrefix, string strTableName, Dictionary<string, string> dicIdMapping, bool isClearNotMatchControl)
        {
            SetControlValue(container, dataSet, needTrimPrefix, strTableName, 0, dicIdMapping, isClearNotMatchControl);
        }

        public static void SetControlValue(Control container, DataSet dataSet, bool needTrimPrefix, string strTableName)
        {
            SetControlValue(container, dataSet, needTrimPrefix, strTableName, 0);
        }
        public static void SetControlValue(Control container, DataSet dataSet, bool needTrimPrefix, string strTableName, int iRowIndex)
        {
            SetControlValue(container, dataSet, needTrimPrefix, strTableName, iRowIndex, new Dictionary<string, string>());
        }

        public static void SetControlValue(Control container, DataSet dataSet, bool needTrimPrefix, string strTableName, int iRowIndex, Dictionary<string, string> dicIdMapping)
        {
            SetControlValue(container, dataSet, needTrimPrefix, strTableName, iRowIndex, dicIdMapping, true);
        }

        public static void SetControlValue(Control container, DataSet dataSet, bool needTrimPrefix, string strTableName, int iRowIndex, Dictionary<string, string> dicIdMapping, bool isClearNotMatchControl)
        {
            string strId = "";
            List<string> lstDialogId = new List<string>();
            foreach (Control child in EnumerateControlsRecursive(container))
            {
                if (child.ID == null)
                    continue;

                strId = needTrimPrefix ? TrimPrefix(child.ID) : child.ID;                

                if (child is GridView)
                {                    
                    if (dataSet.Tables.Contains(strId) == false)
                        continue;

                    ((GridView)child).DataSource = dataSet.Tables[strId];
                    ((GridView)child).DataBind();
                    continue;
                }

                if (needTrimPrefix)
                {
                    SetControlValue(container, child.ID, strTableName, (child is DropDownList) 
                                                                            ? ((DropDownList)child).DataValueField 
                                                                            : (child is ListBox) 
                                                                                ? ((ListBox)child).DataValueField
                                                                                :  strId, dataSet, iRowIndex, dicIdMapping, isClearNotMatchControl);
                }
                else
                {
                    SetControlValue(container, child.ID, strTableName, dataSet, iRowIndex, dicIdMapping, isClearNotMatchControl);
                }
            }
        }

        public static void SetControlValue(Control container, string strControlId, string strDataTableName, DataSet dsData, int iRowIndex)
        {
            SetControlValue(container, strControlId, strDataTableName, null, dsData, iRowIndex, new Dictionary<string,string>(), true);
        }

        public static void SetControlValue(Control container, string strControlId, string strDataTableName, DataSet dsData)
        {
            SetControlValue(container, strControlId, strDataTableName, null, dsData, 0, new Dictionary<string,string>(), true);
        }

        public static void SetControlValue(Control container, string strControlId, string strDataTableName, DataSet dsData, int iRowIndex, Dictionary<string, string> dicIdMapping)
        {
            SetControlValue(container, strControlId, strDataTableName, dsData, iRowIndex, dicIdMapping, true);
        }
        public static void SetControlValue(Control container, string strControlId, string strDataTableName, DataSet dsData, int iRowIndex, Dictionary<string, string> dicIdMapping, bool isClearNotMatchControl)
        {
            SetControlValue(container, strControlId, strDataTableName, null, dsData, iRowIndex, dicIdMapping, isClearNotMatchControl);
        }

        public static void SetControlValue(Control container, string strControlId, string strDataTableName, DataSet dsData, Dictionary<string, string> dicIdMapping)
        {
            SetControlValue(container, strControlId, strDataTableName, null, dsData, 0, dicIdMapping, true);
        }

        public static void SetControlValue(Control container, string strControlId, string strDataTableName, string strColumnName, DataSet dsData, int iRowIndex)
        {
            SetControlValue(container, strControlId, strDataTableName, strColumnName, dsData, iRowIndex, new Dictionary<string, string>(), true);
        }

        public static void SetControlValue(Control container, string strControlId, string strDataTableName, string strColumnName, DataSet dsData, int iRowIndex, Dictionary<string, string> dicIdMapping)
        {
            SetControlValue(container, strControlId, strDataTableName, strColumnName, dsData, iRowIndex, dicIdMapping, true);
        }

        public static void SetControlValue(Control container, string strControlId, string strDataTableName, string strColumnName, DataSet dsData, int iRowIndex, Dictionary<string, string> dicIdMapping, bool isClearNotMatchControl)
        {
            try
            {
                // 轉換ID Mapping
                if (strColumnName == null)
                    strColumnName = dicIdMapping.ContainsKey(strControlId) ? dicIdMapping[strControlId] : strControlId;
                else
                    strColumnName = dicIdMapping.ContainsKey(strColumnName) ? dicIdMapping[strColumnName] : strColumnName;

                if ((container.FindControl(strControlId) == null) ||
                   (dsData.Tables.Contains(strDataTableName) == false))
                    return;



                Control ctrlTarget = container.FindControl(strControlId);

                if ((ctrlTarget is TextBox) ||
                    (ctrlTarget is CheckBox) ||
                    (ctrlTarget is Label) ||
                    (ctrlTarget is Image) ||
                    (ctrlTarget is ImageButton) ||
                    (ctrlTarget is LinkButton) ||
                    (ctrlTarget is HiddenField) ||
                    (ctrlTarget is ListBox) ||
                    (ctrlTarget is RadioButtonList) ||
                    (ctrlTarget is CheckBoxList) ||
                    (ctrlTarget is DropDownList))
                {
                    SetValue(ctrlTarget, strColumnName, dsData.Tables[strDataTableName], iRowIndex, isClearNotMatchControl);
                    return;
                }

                if ((ctrlTarget is GridView))
                {
                    ((GridView)ctrlTarget).DataSource = dsData.Tables[strDataTableName];
                    ((GridView)ctrlTarget).DataBind();
                }

                if ((ctrlTarget is DataList))
                {
                    ((DataList)ctrlTarget).DataSource = dsData.Tables[strDataTableName];
                    ((DataList)ctrlTarget).DataBind();
                }
            }
            catch (Exception ex)
            {
                throw;
            }
        }

        public static DataSet AddValue(string strKey, object oValue)
        {
            return AddValue(strKey, oValue, new DataSet());
        }

        public static DataSet AddValue(string strKey, object oValue, DataSet dsData)
        {
            if (dsData.Tables.Contains(SINGLE_VALUE_TABLE) == false)
                dsData.Tables.Add(new DataTable(SINGLE_VALUE_TABLE));

            AddValue(strKey, oValue, dsData.Tables[SINGLE_VALUE_TABLE]);

            return dsData;
        }


        public static void AddValue(string strKey, object oValue, DataTable dtSource)
        {
            if (dtSource.Rows.Count == 0)
            {
                dtSource.Columns.Add(strKey, typeof(string));
                dtSource.Columns[strKey].ReadOnly = false;
                dtSource.Rows.Add(dtSource.NewRow());
                dtSource.Rows[0][strKey] = StringHelper.ToString(oValue);
                return;
            }
            if (dtSource.Columns.Contains(strKey))
            {
                dtSource.Columns[strKey].ReadOnly = false;
            }
            else
            {
                dtSource.Columns.Add(strKey, typeof(string));
            }
                        
            dtSource.Rows[0][strKey] = StringHelper.ToString(oValue, ",");
        }


        public static void AddValue(Dictionary<string, object> dicValue, DataTable dtSource)
        {
            try
            {
                foreach (string strKey in dicValue.Keys)
                {
                    AddValue(strKey, dicValue[strKey], dtSource);
                }
            }
            catch (Exception ex)
            {
                throw;
            }
        }

        public static void SetReadOnly(Control container, bool isReadOnly)
        {
            foreach (Control child in EnumerateControlsRecursive(container))
            {
                if (child is TextBox)
                    ((TextBox)child).ReadOnly = isReadOnly;
            }
        }

        public static void SetEnabled(Control container, bool isEnabled)
        {
            foreach (Control child in EnumerateControlsRecursive(container))
            {
                if(child is TextBox)
                    ((TextBox)child).Enabled = isEnabled;

            }
        }


        public static int GetRowIndex(GridViewCommandEventArgs e)
        {
            try
            {
                return ((GridViewRow)((ImageButton)e.CommandSource).NamingContainer).RowIndex;
            }
            catch (Exception ex)
            {
                throw;
            }
            return -1;
        }

        public static DataSet CreateModel(Control container)
        {
            return CreateModel(container, false);
        }

        public static DataSet CreateModel(Control container, bool needTrimPrefix)
        {
            return CreateModel(container, needTrimPrefix, new DataSet());
        }

        public static DataSet CreateModel(Control container, bool needTrimPrefix, DataSet returnDataSet)
        {
            
            DataTable dataTable = null;
            DataRow dataRow = null;
            Dictionary<string, object> dicSingleValue = new Dictionary<string, object>();
            Dictionary<string, object> dicSingleValueClientId = new Dictionary<string, object>();
            string strID;
            string strClientId;

            foreach (Control child in EnumerateControlsRecursive(container))
            {
                strID = needTrimPrefix ? TrimPrefix(child.ID) : child.ID;
                strClientId = child.ClientID;

                Control hfGridViewId;
                if (strID == null)
                    continue;

                if (strID.Trim() == "")
                    continue;

                if (child is GridView)
                {
                    hfGridViewId = container.FindControl(((GridView)child).ID + "Id");
                    if(hfGridViewId == null)
                        dataTable = GetDataTable((GridView)child);
                    else
                        dataTable = GetDataTable((GridView)child, ((HiddenField)hfGridViewId).Value.Split(','));
                    dataTable.TableName = strID;

                    returnDataSet.Tables.Add(dataTable);

                    if (hfGridViewId == null)
                        dataTable = GetSelectedRow((GridView)child);
                    else
                        dataTable = GetSelectedRow((GridView)child, ((HiddenField)hfGridViewId).Value.Split(','));

                    if (dataTable != null)
                    {
                        dataTable.TableName = strID + "_SELECTED";
                        returnDataSet.Tables.Add(dataTable);
                    }
                    continue;
                }

                if (child is DataList)
                {
                    hfGridViewId = container.FindControl(((DataList)child).ID + "Id");
                    if (hfGridViewId == null)
                        dataTable = GetDataList((DataList)child);
                    else
                        dataTable = GetDataList((DataList)child, ((HiddenField)hfGridViewId).Value.Split(','));
                    dataTable.TableName = strID;

                    returnDataSet.Tables.Add(dataTable);

                    //if (hfGridViewId == null)
                    //    dataTable = GetSelectedRow((GridView)child);
                    //else
                    //    dataTable = GetSelectedRow((GridView)child, ((HiddenField)hfGridViewId).Value.Split(','));

                    //if (dataTable != null)
                    //{
                    //    dataTable.TableName = strID + "_SELECTED";
                    //    returnDataSet.Tables.Add(dataTable);
                    //}
                    continue;
                }

                if ((child is TextBox) ||
                    (child is Label) ||
                    (child is Image) ||
                    (child is ImageButton) ||
                    (child is LinkButton) ||
                    (child is HiddenField))
                {
                    AddValue(dicSingleValue, strID, (string)ParseControl(child)[0]);
                    AddValue(dicSingleValueClientId, strClientId, (string)ParseControl(child)[0]);                    
                    continue;
                }

                if (child is CheckBox)
                {
                    AddValue(dicSingleValue, strID, (bool)ParseControl(child)[0] ? "Y" : "N");
                    AddValue(dicSingleValueClientId, strClientId, (bool)ParseControl(child)[0] ? "Y" : "N");
                    continue;

                }

                if (child is CheckBoxList)
                {
                    if (((CheckBoxList)child).SelectedItem == null)
                        continue;

                    object[] oReturns = ParseControl(child);
                    AddValue(dicSingleValue, strID, oReturns != null ? oReturns[0] != null ? oReturns[0].ToString() : null : null);
                    AddValue(dicSingleValue, strID + "_Value", oReturns != null ? oReturns[1] != null ? oReturns[1].ToString() : null : null);

                    AddValue(dicSingleValueClientId, strClientId, oReturns != null ? oReturns[0] != null ? oReturns[0].ToString() : null : null);
                    AddValue(dicSingleValueClientId, strClientId + "_Value", oReturns != null ? oReturns[1] != null ? oReturns[1].ToString() : null : null);

                    AddValue(dicSingleValue, ((CheckBoxList)child).DataTextField, oReturns != null ? oReturns[0] != null ? oReturns[0].ToString() : null : null);
                    AddValue(dicSingleValue, ((CheckBoxList)child).DataValueField, oReturns != null ? oReturns[1] != null ? oReturns[1].ToString() : null : null);
                    continue;
                }

                if (child is RadioButtonList)
                {
                    if (((RadioButtonList)child).SelectedItem == null)
                        continue;

                    object[] oReturns = ParseControl(child);
                    AddValue(dicSingleValue, strID, oReturns != null ? oReturns[0] != null ? oReturns[0].ToString() : null : null);
                    AddValue(dicSingleValue, strID + "_Value", oReturns != null ? oReturns[1] != null ? oReturns[1].ToString() : null : null);

                    AddValue(dicSingleValueClientId, strClientId, oReturns != null ? oReturns[0] != null ? oReturns[0].ToString() : null : null);
                    AddValue(dicSingleValueClientId, strClientId + "_Value", oReturns != null ? oReturns[1] != null ? oReturns[1].ToString() : null : null);

                    AddValue(dicSingleValue, ((RadioButtonList)child).DataTextField, oReturns != null ? oReturns[0] != null ? oReturns[0].ToString() : null : null);
                    AddValue(dicSingleValue, ((RadioButtonList)child).DataValueField, oReturns != null ? oReturns[1] != null ? oReturns[1].ToString() : null : null);
                    continue;
                }

                if (child is DropDownList)
                {
                    if (((DropDownList)child).SelectedItem == null)
                        continue;
                    
                    object[] oReturns = ParseControl(child);
                    AddValue(dicSingleValue, strID, oReturns != null ? oReturns[0] != null ? oReturns[0].ToString() : null : null);
                    AddValue(dicSingleValue, strID + "_Value", oReturns != null ? oReturns[1] != null ? oReturns[1].ToString() : null : null);

                    AddValue(dicSingleValueClientId, strClientId, oReturns != null ? oReturns[0] != null ? oReturns[0].ToString() : null : null);
                    AddValue(dicSingleValueClientId, strClientId + "_Value", oReturns != null ? oReturns[1] != null ? oReturns[1].ToString() : null : null);

                    AddValue(dicSingleValue, ((DropDownList)child).DataTextField, oReturns != null ? oReturns[0] != null ? oReturns[0].ToString() : null : null);
                    AddValue(dicSingleValue, ((DropDownList)child).DataValueField, oReturns != null ? oReturns[1] != null ? oReturns[1].ToString() : null : null);
                    continue;
                }

                if (child is ListBox)
                {
                    if (((ListBox)child).SelectedItem == null)
                        continue;

                    object[] oReturns = ParseControl(child);
                    AddValue(dicSingleValue, strID, oReturns != null ? oReturns[0] != null ? oReturns[0].ToString() : null : null);
                    AddValue(dicSingleValue, strID + "_Value", oReturns != null ? oReturns[1] != null ? oReturns[1].ToString() : null : null);

                    AddValue(dicSingleValueClientId, strClientId, oReturns != null ? oReturns[0] != null ? oReturns[0].ToString() : null : null);
                    AddValue(dicSingleValueClientId, strClientId + "_Value", oReturns != null ? oReturns[1] != null ? oReturns[1].ToString() : null : null);

                    AddValue(dicSingleValue, ((ListBox)child).DataTextField, oReturns != null ? oReturns[0] != null ? oReturns[0].ToString() : null : null);
                    AddValue(dicSingleValue, ((ListBox)child).DataValueField, oReturns != null ? oReturns[1] != null ? oReturns[1].ToString() : null : null);
                    continue;
                }
            }

            dataTable = new DataTable();
            dataTable.TableName = SINGLE_VALUE_TABLE;

            foreach (string strKey in dicSingleValue.Keys)
                if(string.IsNullOrEmpty(strKey) == false)
                    dataTable.Columns.Add(strKey, typeof(string));

            dataRow = dataTable.NewRow();

            foreach (string strKey in dicSingleValue.Keys)
                if(string.IsNullOrEmpty(strKey) == false)
                    dataRow[strKey] = dicSingleValue[strKey];

            dataTable.Rows.Add(dataRow);

            if (returnDataSet.Tables.Contains(SINGLE_VALUE_TABLE))
            {
                for (int i = 0; i < dataTable.Columns.Count; i++)
                {
                    if (returnDataSet.Tables[SINGLE_VALUE_TABLE].Columns.Contains(dataTable.Columns[i].ColumnName) == false)                    
                        returnDataSet.Tables[SINGLE_VALUE_TABLE].Columns.Add(dataTable.Columns[i].ColumnName, typeof(string));
                    returnDataSet.Tables[SINGLE_VALUE_TABLE].Columns[dataTable.Columns[i].ColumnName].ReadOnly = false;
                    returnDataSet.Tables[SINGLE_VALUE_TABLE].Rows[0][dataTable.Columns[i].ColumnName] = dataTable.Rows[0][i].ToString();
                }
            }
            else
            {
                returnDataSet.Tables.Add(dataTable);
            }

            dataTable = new DataTable();
            dataTable.TableName = SINGLE_VALUE_TABLE_CLIENT_ID;
            foreach (string strKey in dicSingleValueClientId.Keys)
                if(string.IsNullOrEmpty(strKey) == false)
                    dataTable.Columns.Add(strKey, typeof(string));

            dataRow = dataTable.NewRow();

            foreach (string strKey in dicSingleValueClientId.Keys)
                if(string.IsNullOrEmpty(strKey) == false)
                    dataRow[strKey] = dicSingleValueClientId[strKey];

            dataTable.Rows.Add(dataRow);

            if (returnDataSet.Tables.Contains(SINGLE_VALUE_TABLE_CLIENT_ID))
            {
                for (int i = 0; i < dataTable.Columns.Count; i++)
                {
                    if (returnDataSet.Tables[SINGLE_VALUE_TABLE_CLIENT_ID].Columns.Contains(dataTable.Columns[i].ColumnName) == false)
                        returnDataSet.Tables[SINGLE_VALUE_TABLE_CLIENT_ID].Columns.Add(dataTable.Columns[i].ColumnName, typeof(string));
                    returnDataSet.Tables[SINGLE_VALUE_TABLE_CLIENT_ID].Columns[dataTable.Columns[i].ColumnName].ReadOnly = false;
                    returnDataSet.Tables[SINGLE_VALUE_TABLE_CLIENT_ID].Rows[0][dataTable.Columns[i].ColumnName] = dataTable.Rows[0][i].ToString();
                }
            }
            else
            {
                returnDataSet.Tables.Add(dataTable);
            }

            return returnDataSet;
        }

        private static void AddValue(Dictionary<string, object> dicSource, string strKey, object oValue)
        {
            try
            {
                if (dicSource.ContainsKey(strKey))
                    dicSource[strKey] = oValue;
                else
                    dicSource.Add(strKey, oValue);
                
            }
            catch (Exception ex)
            {
                throw;
            }
        }

        public static string TrimPrefix(string strSource)
        {
            int iIndex = 0;

            if (strSource == null)
                return strSource;

            while ((strSource[iIndex] >= 'a') && (strSource[iIndex] <= 'z') && (iIndex < strSource.Length))
                iIndex++;

            return strSource.Substring(iIndex);
        }
    }
}
